Skip to content

Migrate away from c-t-go/x509 and c-t-go/asn1 #198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Mar 18, 2025

Conversation

phbnf
Copy link
Collaborator

@phbnf phbnf commented Mar 18, 2025

Towards #44

This PR migrates away from certificate-transparency-go/x509 and certificate-transparency-go/asn1. A follow up PR will drop dependency on certificate-transparency-go/tls.

To allow for such a transition, this PR does a few things:

  • modifies how certificates and their fields are printed: c-t-go/x509 has a lot of methods to print certificates and their fields. crypto/x509 does not have methods to print full certs anymore, but individual fields that implement the stringer interface can be printed. We only every used full certificate printing in chain_validation_test.go, so I've simply replaced this with printing its md5sum for now. This allows to delete the full certificate printing methods. If we need them again, we can use other libraries.
  • moves BuildPrecertTBS from c-t-go/x509 to x509util/ct
  • changes how isPreIssuer works, since the crypto/x509 library won't parse CT extended key usage extensions.

phbnf added 11 commits March 18, 2025 10:58
# Conflicts:
#	internal/scti/storage.go

# Conflicts:
#	internal/scti/ctlog.go

# Conflicts:
#	internal/scti/chain_validation.go
#	internal/scti/handlers_test.go
#	internal/scti/signatures_test.go

# Conflicts:
#	ctlog.go
# Conflicts:
#	internal/scti/requestlog.go
# Conflicts:
#	ctlog.go

# Conflicts:
#	ctlog.go

# Conflicts:
#	internal/scti/chain_validation_test.go
# Conflicts:
#	internal/x509util/x509util.go

# Conflicts:
#	internal/x509util/x509util.go
# Conflicts:
#	internal/scti/handlers.go
# Conflicts:
#	internal/x509util/ct.go
#	internal/x509util/ct_test.go
@phbnf phbnf marked this pull request as ready for review March 18, 2025 11:19
Copy link
Collaborator

@AlCutter AlCutter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tangential thought; is types really two separate packages, e.g. rfc6962 and staticct?

// - allow pre-certificates and chains with pre-issuers
// - allow certificate without policing them since this is not CT's responsibility
// See /internal/x509fork/README.md for further information.
verifyOpts := x509fork.VerifyOptions{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming idea for this fork package: lax509 :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sending a different PR to avoid making this one even larger.

@@ -690,7 +692,7 @@ func TestPreIssuedCert(t *testing.T) {
t.Fatalf("failed to ValidateChain: %v", err)
}
for i, c := range chain {
t.Logf("chain[%d] = \n%s", i, x509util.CertificateToString(c))
t.Logf("chain[%d] = \n%s", i, md5.Sum(c.Raw))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

md5?

Would printing the Subject make it easier to tie back to the certs in the chain?

Comment on lines +512 to +520
func isPreIssuer(cert *x509.Certificate) bool {
// Look for the extension in the Extensions field and not ExtKeyUsage
// since crypto/x509 does not recognize this extension as an ExtKeyUsage.
for _, ext := range cert.Extensions {
if types.OIDExtKeyUsageCertificateTransparency.Equal(ext.Id) {
return true
}
}
return false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen this in a couple of places, feels like it might reasonably live exported in x509util?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - there's a TODO to merge them, I'll do this in a followup PR. This PR was 90% done before the other isPreissuer was added.

Comment on lines +26 to +31
var (
oidExtensionAuthorityKeyId = asn1.ObjectIdentifier{2, 5, 29, 35}
// These extensions are defined in RFC 6962 s3.1.
oidExtensionCTPoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3}
oidExtensionKeyUsageCertificateTransparency = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 4}
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could/should these live next to the other RFC6962 OIDs currently in types?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They could, yes: but what's the benefit?

I decided to leave them here because:

  • we're only talking about two vars, defined in the RFC that and haven't changed in 10+ years
  • it makes this file more readable
  • x509util is really what it says: it's a util for x509 and it does not import anything else, it just depends on standard libraries.

Comment on lines +70 to +77
for i, ext := range tbs.Extensions {
if ext.Id.Equal(oid) {
if extAt != -1 {
return nil, errors.New("multiple extensions of specified type present")
}
extAt = i
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you may be able to use slices.IndexFunc here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can yeah. I'll leave it for now in this PR since these methods are being copied from c-t-go, and can send a followup PR.

I find that the end result is not necessarily easier to read though, especially here since we need to use the function twice to find duplicate extensions. The current implementation only requires one loop iteration, this one two. Plus, the base implementation of slices.Index slices.IndexFunc aren't really bringing any magic. I've done a fair amount of function programming before, and I really really really like and the slice package, but for very simple usecases like this I find it way less readable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack - will do in a followup PR, this PR is trying no to change the implementation of these functions too much and to copy them over from c-t-go.

Comment on lines +152 to +157
for i, ext := range tbs.Extensions {
if ext.Id.Equal(oidExtensionAuthorityKeyId) {
keyAt = i
break
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be able to use slices.IndexFunc here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack - will do in a followup PR, this PR is trying no to change the implementation of these functions too much and to copy them over from c-t-go.

//
// Deprecated: if s was returned by [SystemCertPool], Subjects
// will not include the system roots.
// Undeprecated in this fork.
Copy link
Contributor

@roger2hk roger2hk Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be weird to have only "Undeprecated in this fork" after merging this PR. Can we mention this is deprecated in the original package and add a link to that?

https://pkg.go.dev/crypto/x509#CertPool.Subjects

Comment on lines +140 to +147
seenCTEKU := false
for _, ext := range preIssuer.Extensions {
if ext.Id.Equal(oidExtensionKeyUsageCertificateTransparency) {
seenCTEKU = true
break
}
}
if !seenCTEKU {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could slices.ContainsFunc be used here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack - will do in a followup PR, this PR is trying no to change the implementation of these functions too much and to copy them over from c-t-go.

@phbnf phbnf merged commit e45de5e into transparency-dev:main Mar 18, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants